<?php
/**
 * Created by PhpStorm.
 * User: wumengmeng <wu_mengmeng@foxmail.com>
 * Date: 2019/4/26 0026
 * Time: 14:35
 */

namespace HiCommon\Service;

use HiCommon\Repository\OrderCheckpointRefundRepository;
use HiCommon\Repository\OrderCheckpointVehicleRepository;
use HiCommon\Repository\OrderPayRefundRepository;
use HiCommon\Repository\OrderPayRepository;
use HiCommon\Repository\OrderRepairstoreRepository;
use HiCommon\Repository\RoadRescueOrderRepository;
use HiCommon\Repository\StoreOrderRefundRepository;
use HiCommon\Repository\StoreOrderRepository;

class PayRefundService extends BaseService
{

    /**
     * 线上支付-退款
     *
     *
     * @return array|void
     * @author wumengmeng <wu_mengmeng@foxmail.com>
     */
    public function api_online_pay_refund($s_order_sn = '',$s_refund_sn = ''){

        $s_refund_sn = str_trim($s_refund_sn);//售后单号
        $s_order_sn = str_trim($s_order_sn);//订单编号
        if(strlen($s_refund_sn) <= 0 ){
            return hello_error('售后单号不能为空');
        }
        if(strlen($s_order_sn) <= 0 ){
            return hello_error('订单编号不能为空');
        }

        //查询支付信息
        $result = PayRefundService::online_pay_data($s_order_sn,$s_pay_type,$s_order_type,$n_total_fee);

        if($result['state'] != 0){
            return $result;
        }

        //处理退款逻辑 根据订单类型进行不同的逻辑操作
        $result = PayRefundService::deal_with_refund_logic_all($s_order_type,$s_order_sn,$s_refund_sn,$n_refund_fee);

        if($result['state'] != 0){
            return $result;
        }

        //退款操作 根据支付类型进行不同的逻辑操作
        $result = PayRefundService::api_refund_all($s_pay_type,$s_order_sn,$s_refund_sn,$n_total_fee,$n_refund_fee);

        if($result['state'] == 0){
            /*通知队列-订单退款通知*/
            queue_in_notice_order_refund($s_order_sn,$s_order_type,$s_refund_sn);

            if(strrpos($s_order_sn,'NJYY') !== false){
                //队列-返还预约数量
                predis_appoint_num_queue_in(['order_sn'=>$s_order_sn]);
            }

        }

        return $result;
    }

    public function online_pay_data($s_order_sn = '',&$s_pay_type = '',&$s_order_type = '',&$n_total_fee = 0){

        //查询支付信息
        $arr_where = ['order_sn'=>$s_order_sn];
        $arr_option = [
          'field'=>['id','order_sn','pay_type','order_type','pay_fee','total_fee']
        ];
        $result = OrderPayRepository::base_get_one($arr_where,$arr_option);
        if(is_null($result)){
            return hello_error('退款失败',[],'支付信息不存在');
        }
        $arr_order_pay = $result->toarray();
        $s_pay_type = $arr_order_pay['pay_type'];
        $s_order_type = $arr_order_pay['order_type'];

        $n_total_fee = $arr_order_pay['total_fee'];//用户总支付金额 ：单位 分
        //        $n_refund_fee = 0;//退款金额 ：单位 分

        if(!in_array($s_order_type,['njyy','ptshp','wxfw','wxby','dljy'])){
            return hello_error('支付数据异常',[],'订单类型错误：njyy-年检预约订单,ptshp-普通商品,wxfw-维修服务,wxby-维修保养,dljy-道路救援');
        }
        if(!in_array($s_pay_type,['wxmini','wxapp','aliapp'])){
            return hello_error('支付方式错误');
        }
        return  hello_success('成功');
    }

    public function deal_with_refund_logic_all($s_order_type = '',$s_order_sn = '',$s_refund_sn = '',&$n_refund_fee = 0){
        if($s_order_type == 'njyy'){
            /*年检预约单-退款逻辑处理*/
            $result = PayRefundService::deal_with_refund_logic_for_njyy($s_refund_sn,$n_refund_fee);
        }
        if($s_order_type == 'ptshp'){
            /*普通商品单-退款逻辑处理*/
            $result = PayRefundService::deal_with_refund_logic_for_ptshp($s_refund_sn,$n_refund_fee);
        }
        if($s_order_type == 'wxfw'){
            /*维修服务单-退款逻辑处理*/
            $result = PayRefundService::deal_with_refund_logic_for_wxfw($s_refund_sn,$n_refund_fee);
        }
        if($s_order_type == 'wxby'){
            /*维修保养单-退款逻辑处理*/
            $result = PayRefundService::deal_with_refund_logic_for_wxby($s_refund_sn,$n_refund_fee);
        }
        if($s_order_type == 'dljy'){
            /*道路救援-退款逻辑处理*/
            $result = PayRefundService::deal_with_refund_logic_for_dljy($s_refund_sn,$n_refund_fee);
        }
        return $result;
    }

    /*年检预约单-退款逻辑处理*/
    public function deal_with_refund_logic_for_njyy($s_refund_sn = '',&$n_refund_fee = 0){

        //查询申请数据
        $arr_where = ['refund_sn'=>$s_refund_sn];
        $arr_option = [
          'with'=>['order_checkpoint'],
        ];
        $result = OrderCheckpointRefundRepository::base_get_one($arr_where,$arr_option);
        if(is_null($result)){
            return hello_error('售后信息不存在');
        }
        $arr_order_checkpoint_refund = $result->toarray();

        if($arr_order_checkpoint_refund['apply_refund_state'] != 2 ){
            return hello_error('状态异常，无法操作');
        }
        $arr_order = $arr_order_checkpoint_refund['order_checkpoint'];
        $n_id = $arr_order['id'];
        $n_refund_id = $arr_order_checkpoint_refund['id'];
        $n_refund_fee = intval($arr_order_checkpoint_refund['refund_price']*100);


        //申请设置为已退款状态 车辆子表和退款申请表
        $n_apply_refund_state = 3;
        $s_refund_time = time_to_ymdhis();
        $n_order_checkpoint_vehicle_id = $arr_order_checkpoint_refund['order_checkpoint_vehicle_id'];
        if($n_order_checkpoint_vehicle_id > 0){

            //单独设置一个为已退款
            $arr_where = ['id'=>$n_order_checkpoint_vehicle_id];
            $arr_data = [
              'apply_refund_state'=>$n_apply_refund_state,
              //              'check_state'=>9,
              //              'checked_at'=>$s_refund_time
            ];
            $res = OrderCheckpointVehicleRepository::edit_by_where($arr_where,$arr_data);
            if($res === false){
                return hello_error('退款失败',[],'车辆子单数据修改失败');
            }
        }


        $arr_where = ['id'=>$n_refund_id];
        $arr_data = ['apply_refund_state'=>$n_apply_refund_state,'refund_time'=>$s_refund_time];
        $res = OrderCheckpointRefundRepository::edit_by_where($arr_where,$arr_data);
        if($res === false){
            return hello_error('退款失败',[],'退款申请数据修改失败');
        }

        //主表联动操作
        $res = OrderCheckpointService::deal_fail_single_other($n_id,$s_refund_time);

        return $res;
    }

    /*普通商品单-退款逻辑处理*/
    public function deal_with_refund_logic_for_ptshp($s_refund_sn = '',&$n_refund_fee = 0){
        $arr_where = ['refund_no' => $s_refund_sn];
        $arr_option['with'] = ['get_refund_price', 'store_order'];
        $refund_ary = StoreOrderRefundRepository::get_one_by_where($arr_where, $arr_option)->toarray();

        $refund_amount = 0.00;
        //申请退款退回运费
        if($refund_ary['apply_type'] == 1){
            $refund_amount = $refund_ary['store_order']['delivery_price'];//运费
        }

        foreach ($refund_ary['get_refund_price'] as $key => $item) {
            $value = $item['get_order_goods'];
            $refund_amount += $value['refund_price'];
            if ($refund_ary['get_order_goods']['apply_type'] == 3) {//仅在退回货物后回收库存
                GoodsProductRepository::increase_num($value['goods_product_id'], 'stock', $value['goods_num']);
            }
        }
        $n_refund_fee = $refund_amount * 100;

        $up_array = ['apply_state' => 4, 'refund_amount' => $refund_amount, 'deal_at' => date('Y-m-d H:i:s')];

        //更新退单状态
        $res = StoreOrderRefundRepository::edit_one_by_where(['id' => $refund_ary['id']], (array)$up_array);
        //更新订单主表退款金额
        $n_id = $refund_ary['store_order_id'];
        StoreOrderRepository::increase_num($n_id, 'refund_price', $refund_amount);

        if ($res) {
            return hello_success('操作成功');
        }

        return hello_error('退款失败',[],'订单状态更新失败');
    }

    /*维修服务单-退款逻辑处理*/
    public function deal_with_refund_logic_for_wxfw($s_refund_sn = '',&$n_refund_fee = 0){
        $arr_where = ['order_number' => $s_refund_sn];
        $arr_option['field'] = ['id','pay_price'];

        $order = OrderRepairstoreRepository::get_one_by_where($arr_where, $arr_option)->toArray();

        $n_refund_fee = $order['pay_price'] * 100;//退款金额

        $arr_input = [
            'id' => $order['id'],
            'pay_status' => 3,
            'refund_price' => $order['pay_price'],
            'refund_time' => date('Y-m-d H:i:s')
        ];
        $res = OrderRepairstoreRepository::edit_one($arr_input);
        if ($res) {
            return hello_success('操作成功');
        }

        return hello_error('退款失败',[],'订单状态更新失败');
    }

    /*维修保养单-退款逻辑处理*/
    public function deal_with_refund_logic_for_wxby($s_refund_sn = '',&$n_refund_fee = 0){
        $arr_where = ['order_number' => $s_refund_sn];
        $arr_option['field'] = ['id','pay_price'];

        $order = OrderRepairstoreRepository::get_one_by_where($arr_where, $arr_option)->toArray();

        $n_refund_fee = $order['pay_price'] * 100;//退款金额

        $arr_input = [
            'id' => $order['id'],
            'pay_status' => 3,
            'refund_price' => $order['pay_price'],
            'refund_time' => date('Y-m-d H:i:s')
        ];
        $res = OrderRepairstoreRepository::edit_one($arr_input);
        if ($res) {
            return hello_success('操作成功');
        }

        return hello_error('退款失败',[],'订单状态更新失败');
    }

    /*道路救援-退款逻辑处理*/
    public function deal_with_refund_logic_for_dljy($s_refund_sn = '',&$n_refund_fee = 0){
        $arr_where = ['refund_no' => $s_refund_sn];
        $arr_option['field'] = ['id','price','pay_time','shop_id','user_id','pid'];

        $order = RoadRescueOrderRepository::get_one_where($arr_where, $arr_option)->toArray();

        $n_refund_fee = '0';  //退款金额
        $deduct_price = '0';  //扣除金额

        //如果订单不超过5分钟
        $lv = 0;  //扣款比例
        //获取当前门店配置的扣款比例
        $shop = \HiCommon\Repository\ShopRepository::find_one( $order['shop_id'] , ['id','deduct_price']);
        if( !empty( $shop ) ){
            $lv = $shop['deduct_price'];
        }
        if( time() - strtotime( $order['pay_time']  ) < 5 * 60  ){
            $n_refund_fee = $order['price'] * 100;//退款金额
        }else{
            $deduct_price = round( $order['price'] * $lv / 100  ,  2);
            $n_refund_fee = (int) ( ( $order['price'] - $deduct_price ) * 100);
        }
        $arr_input = [
            'id' => $order['id'],
            'status' => 22,
            'refund_price' => $n_refund_fee/100,   //实际退款金额
            'deduct_price' => $deduct_price,   //实际扣除金额
            'refund_time_success' => date('Y-m-d H:i:s')
        ];
        $res = RoadRescueOrderRepository::edit_one($arr_input);
        if ($res) {
            return hello_success('操作成功');
        }

        return hello_error('退款失败',[],'订单状态更新失败');
    }







    /****************************************** 退款操作 *****************************************/

    /*退款操作中转*/
    public function api_refund_all($s_order_type = '',$s_order_no = '',$s_refund_no = '',$n_total_fee = 0,$n_refund_fee = 0){

        //支付降比
        $n_total_fee = intval($n_total_fee);//实际支付金额已经降比 不需要降比
        $n_refund_fee = intval(pay_ratio_down($n_refund_fee));


        //添加退款表记录
        $arr_data = [
          'order_sn'=>$s_refund_no,
          'out_trade_no'=>$s_order_no,
          'out_refund_no'=>$s_refund_no,
          'total_fee'=>$n_total_fee,
          'refund_fee'=>$n_refund_fee,
//          'type'=>$s_order_type,
        ];

        $res = OrderPayRefundRepository::base_add_one($arr_data)->toarray();
        if(empty($res)){
            hello_error('退款失败',[],'添加退款记录失败');
        }

        //退款操作
        if($s_order_type == 'wxmini'){
            /*微信小程序-退款操作*/
            $s_refund_type = 'miniapp';
            $arr_option = ['refund_desc'=>'微信小程序退款'];
            $result = PayRefundService::api_wx_refund($s_refund_type,$s_order_no,$s_refund_no,$n_total_fee,$n_refund_fee,$arr_option);
        }
        elseif($s_order_type == 'wxapp'){
            /*微信app-退款操作*/
            $s_refund_type = 'app';
            $arr_option = ['refund_desc'=>'微信app退款'];
            $result = PayRefundService::api_wx_refund($s_refund_type,$s_order_no,$s_refund_no,$n_total_fee,$n_refund_fee,$arr_option);
        }
        elseif($s_order_type == 'aliapp'){
            /*支付宝app-退款操作*/
            $arr_option = ['refund_desc'=>'支付宝app退款'];
            $result = PayRefundService::api_ali_refund($s_order_no,$s_refund_no,$n_refund_fee,$arr_option);
        }
        else{
            $result = hello_error('失败');
        }

        return $result;
    }

    /*微信退款*/
    public function api_wx_refund($s_refund_type = '',$s_out_trade_no = '',$s_out_refund_no = '',$n_total_fee = 0,$n_refund_fee = 0,$arr_option = []){
        //退款操作
        $arr_order = [
          'out_trade_no'=>$s_out_trade_no,
          'out_refund_no'=>$s_out_refund_no,
          'total_fee'=>$n_total_fee,
          'refund_fee'=>$n_refund_fee,
          'type'=>$s_refund_type,
        ];
        $arr_order = array_replace_recursive($arr_order,$arr_option);
        $result = PayYanSongDaService::pay_wechat()->refund($arr_order);
        //        LogService::wright_log_for_wechat_refund('Wechat Refund',$result,'info');

        $n_refund_ok = $result['return_code'] == 'SUCCESS' && $result['result_code'] == 'SUCCESS';
        if($n_refund_ok){
            return  hello_success('退款成功',$result);
        }
        else{
            $error_msg = wechat_refund_error_code($result['err_code']);
            return  hello_error($error_msg,$result,$result['err_code']);
        }
    }

    /*支付宝退款*/
    public function api_ali_refund($s_out_trade_no,$s_refund_no,$n_refund_fee,$arr_option){
        //退款操作
        $arr_order = [
          'out_trade_no'=>$s_out_trade_no,
          'out_request_no'=>$s_refund_no,
          'refund_amount'=>fee_to_money($n_refund_fee),
        ];
        $arr_order = array_replace_recursive($arr_order,$arr_option);
        $result = PayYanSongDaService::pay_ali()->refund($arr_order);
        //        LogService::wright_log_for_wechat_refund('Wechat Refund',$result,'info');

        $result = json_decode($result,true);
        $n_refund_ok = $result['code'] == '10000' && $result['msg'] == 'Success';

        if($n_refund_ok){
            return  hello_success('退款成功',$result);
        }
        else{
            $s_msg = $result['sub_msg'];
            return hello_error('退款失败',[],$s_msg);
        }
    }





}